import EditBase from "./EditBase";
import { getEditIndex, toPointGeojson } from "./utils";

export default class EditControl extends EditBase {
	constructor(map) {
		super(map);

		this.editLayerId = "edit-control-layer";

		this.editIndex = -1;

		this.initEditLayer();
	}

	initEditLayer() {
		const { map, editLayerId } = this;

		const editLControLayer = {
			id: editLayerId,
			type: "circle",
			source: {
				type: "geojson",
				data: {
					type: "FeatureCollection",
					features: [],
				},
			},
			paint: {
				"circle-color": "#F84C4C", // red
				"circle-radius": 5,
				"circle-opacity": 1,
			},
		};

		map.addLayer(editLControLayer);

		this.editSource = map.getSource(editLayerId);
	}

	bindEvents(callback) {
		const { map, editLayerId } = this;

		this.enterFunc = this.onMouseEnter.bind(this);
		this.leaveFunc = this.onMouseLeave.bind(this);
		this.downFunc = this.onMouseDown.bind(this);
		this.moveFunc = this.onMove.bind(this, callback);
		this.upFunc = this.onUp.bind(this);

		map.on("mouseenter", editLayerId, this.enterFunc);
		map.on("mouseleave", editLayerId, this.leaveFunc);
		map.on("mousedown", editLayerId, this.downFunc);
	}

	onMouseEnter() {
		const { map, canvas, editLayerId } = this;
		map.setPaintProperty(editLayerId, "circle-color", "#3bb2d0");
		canvas.style.cursor = "move";
	}

	onMouseLeave() {
		const { map, canvas, editLayerId } = this;
		map.setPaintProperty(editLayerId, "circle-color", "#3887be");
		canvas.style.cursor = "";
	}

	onMouseDown(e) {
		const { map, canvas } = this;
		// Prevent the default map drag behavior.
		e.preventDefault();

		canvas.style.cursor = "grab";

		const zoom = map.getZoom();
		const radius = 0.1 * (1 / zoom); // 根据zoom设置半径
		this.editIndex = getEditIndex(this.points, e.lngLat, radius);

		// console.log("editIndex", this.editIndex);

		map.on("mousemove", this.moveFunc);
		map.once("mouseup", this.upFunc);
	}

	onUp() {
		const { canvas, map } = this;

		canvas.style.cursor = "";
		map.off("mousemove", this.moveFunc);
	}

	onMove(callback, e) {
		const { canvas, editIndex, points, editSource } = this;

		const coords = e.lngLat;
		canvas.style.cursor = "grabbing";

		points[editIndex] = [coords.lng, coords.lat];

		const data = toPointGeojson(points);
		editSource.setData(data);

		callback(points);
	}

	updateEditSource(points) {
		const data = toPointGeojson(points);
		this.editSource.setData(data);

		this.points = points;
	}

	destroy() {
		const { map, editLayerId } = this;

		map.off("mouseenter", this.enterFunc);
		map.off("mouseleave", this.leaveFunc);
		map.off("mousedown", this.downFunc);

		map.removeLayer(editLayerId);
		map.removeSource(editLayerId);
	}
}
